package org.jeecg.modules.wangyue.controller.applogin;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wangyue.constant.CodeTypeConstant;
import org.jeecg.modules.wangyue.constant.DelFlagConstant;
import org.jeecg.modules.wangyue.constant.IsBlockConstant;
import org.jeecg.modules.wangyue.constant.IsPromotionConstant;
import org.jeecg.modules.wangyue.entity.UserBasic;
import org.jeecg.modules.wangyue.model.req.ReqCommonModel;
import org.jeecg.modules.wangyue.model.req.ReqUserLoginModel;
import org.jeecg.modules.wangyue.service.IContractTemplateService;
import org.jeecg.modules.wangyue.service.IUserBasicService;
import org.jeecg.modules.wangyue.utils.CommonUtil;
import org.jeecg.modules.wangyue.utils.DanMiSmsUtil;
import org.jeecg.modules.wangyue.utils.DateUtil;
import org.jeecg.modules.wangyue.utils.SendSmsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
* @Description: 用户登录相关接口
* @Author: jeecg-boot
* @Date:   2023-06-30
* @Version: V1.0
*/
@Slf4j
@Api(tags="用户登录相关接口")
@RestController
@RequestMapping("/wangyue/applogin/userLogin")
public class UserLoginController extends JeecgController<UserBasic, IUserBasicService> {
   @Autowired
   private IUserBasicService userBasicService;
   @Autowired
   private IContractTemplateService contractTemplateService;
   @Autowired
   private RedisTemplate<String, String> redisTemplate;



    /**
     * 用户登录校验
     * @return
     */
   @AutoLog(value = "用户登录校验")
   @ApiOperation(value="用户登录校验", notes="用户登录校验")
   @PostMapping(value = "/userLogin")
   public Result<?> userLogin(@RequestBody ReqUserLoginModel reqUserLoginModel){
       String account = reqUserLoginModel.getAccount();
       String password = reqUserLoginModel.getPassword();
       if(oConvertUtils.isEmpty(account) || oConvertUtils.isEmpty(password)){
           return Result.error("必输项不能为空");
       }

       QueryWrapper<UserBasic> userBasicQueryWrapper = new QueryWrapper<>();
       userBasicQueryWrapper.eq("account", account);
       userBasicQueryWrapper.eq("is_block", IsBlockConstant.no);
       userBasicQueryWrapper.eq("del_flag", DelFlagConstant.normal);
       UserBasic userBasic = userBasicService.getOne(userBasicQueryWrapper); //通过输入账号查询用户信息
       if(oConvertUtils.isNotEmpty(userBasic)){
           String pwdMd5 = SecureUtil.md5(password); //输入密码进行MD5加密

           //校验输入密码是否正确
           if(!pwdMd5.equals(userBasic.getPassword())){
               return Result.error("账号或密码错误");
           }

           //生成token，放入redis中
           String token = CommonUtil.uuid32();
           redisTemplate.opsForValue().set("token_" + userBasic.getId(), token);

           //将token和账号信息返回给前端
           JSONObject jsonObject = new JSONObject();
           jsonObject.put("userId", userBasic.getId());
           jsonObject.put("account", userBasic.getAccount());
           jsonObject.put("token", token);
           return Result.OK("账号密码正确", jsonObject);
       }
       return Result.error("账号不存在");
   }


   /**
     * 用户退出
     * @return
    */
   @AutoLog(value = "用户退出")
   @ApiOperation(value="用户退出", notes="用户退出")
   @PostMapping(value = "/userQuit")
   public Result<?> userQuit(@RequestBody ReqUserLoginModel reqUserLoginModel){
       String userId = reqUserLoginModel.getUserId();
       String token = reqUserLoginModel.getToken();

       if(oConvertUtils.isNotEmpty(userId)){
           String tk = redisTemplate.opsForValue().get("token_" + userId); //取出该userId存放在redis内的token
           if(oConvertUtils.isNotEmpty(tk) && tk.equals(token)){ //如果取出来的token不为空，且与输入的token一致，则从redis清除。
               redisTemplate.delete("token_" + userId);
           }
            return Result.OK("用户退出成功");
       }
       return Result.error("用户id不能为空");
   }

    /**
     * 用户注册
     * @return
     */
    @AutoLog(value = "用户注册")
    @ApiOperation(value="用户注册", notes="用户注册")
    @PostMapping(value = "/userSignUp")
    public Result<?> userSignUp(@RequestBody ReqUserLoginModel reqUserLoginModel){
        String account = reqUserLoginModel.getAccount();
        String password = reqUserLoginModel.getPassword();
        String phoneCode = reqUserLoginModel.getPhoneCode();
        String isPromotion = reqUserLoginModel.getIsPromotion();
        String promotionCode = reqUserLoginModel.getPromotionCode();
        String roleType = reqUserLoginModel.getRoleType();
        if (oConvertUtils.isEmpty(account)){
            return Result.error("账号不能为空");
        }
        if(oConvertUtils.isEmpty(password)){
            return Result.error("密码不能为空");
        }
        if(userBasicService.isAccountRegistered(account)){ //判断账号是否被注册过
            return Result.error("该账号已存在");
        }
        if(IsPromotionConstant.yes.equals(isPromotion) && !userBasicService.isPromoterExist(promotionCode)){
            return Result.error("推广码(" + promotionCode + ")的推广人不存在");
        }

        String code = redisTemplate.opsForValue().get("signUp_" + account);
        if(oConvertUtils.isNotEmpty(phoneCode) && phoneCode.equals(code)){ //校验短信验证码
            if(userBasicService.userSignUp(account, password, isPromotion, promotionCode, roleType)){
                redisTemplate.delete("signUp_" + account); //注册成功，则清除注册短信验证码
                return Result.OK("用户注册成功");
            }
            return Result.error("用户注册失败");
        }
        return Result.error("验证码错误");
    }


    /**
     * 判断账号是否注册
     * @return
     */
    @AutoLog(value = "判断账号是否注册")
    @ApiOperation(value="判断账号是否注册", notes="判断账号是否注册")
    @PostMapping(value = "/isAccountRegistered")
    public Result<?> isAccountRegistered(@RequestBody ReqUserLoginModel reqUserLoginModel){
        String account = reqUserLoginModel.getAccount();
        if(oConvertUtils.isEmpty(account)){
            return Result.error("必输项不能为空");
        }

        JSONObject jsonObject = new JSONObject();
        if(!userBasicService.isAccountRegistered(account)){
            jsonObject.put("isRegistered", "no");
            return Result.OK("账号没有被注册过", jsonObject);
        }
        jsonObject.put("isRegistered", "yes");
        return Result.OK("账号已注册过", jsonObject);
    }


    /**
     * 判断推广人是否存在
     * @return
     */
    @AutoLog(value = "判断推广人是否存在")
    @ApiOperation(value="判断推广人是否存在", notes="判断推广人是否存在")
    @PostMapping(value = "/isPromoterExist")
    public Result<?> isPromoterExist(@RequestBody ReqUserLoginModel reqUserLoginModel){
        String promotionCode = reqUserLoginModel.getPromotionCode();
        if(oConvertUtils.isEmpty(promotionCode)){
            return Result.error("必输项不能为空");
        }

        JSONObject jsonObject = new JSONObject();
        if(userBasicService.isPromoterExist(promotionCode)){
            jsonObject.put("isExist", "yes");
            return Result.OK("推广码的推广人存在", jsonObject);
        }
        jsonObject.put("isExist", "no");
        return Result.OK("推广码的推广人不存在", jsonObject);
    }


    /**
     * 用户忘记密码
     * @return
     */
    @AutoLog(value = "用户忘记密码")
    @ApiOperation(value="用户忘记密码", notes="用户忘记密码")
    @PostMapping(value = "/userforgotPwd")
    public Result<?> userforgotPwd(@RequestBody ReqUserLoginModel reqUserLoginModel){
        String account = reqUserLoginModel.getAccount();
        String phoneCode = reqUserLoginModel.getPhoneCode();
        String newPassword = reqUserLoginModel.getNewPassword();
        if (oConvertUtils.isEmpty(account)){
            return Result.error("账号不能为空");
        }
        if(oConvertUtils.isEmpty(newPassword)){
            return Result.error("新密码不能为空");
        }

        String code = redisTemplate.opsForValue().get("forgotPwd_" + account);
        if(oConvertUtils.isNotEmpty(phoneCode) && phoneCode.equals(code)){ //校验短信验证码
            UpdateWrapper<UserBasic> userBasicUpdateWrapper = new UpdateWrapper<>();
            userBasicUpdateWrapper.eq("account", account);
            userBasicUpdateWrapper.eq("is_block", IsBlockConstant.no);
            userBasicUpdateWrapper.eq("del_flag", DelFlagConstant.normal);
            userBasicUpdateWrapper.set("password", SecureUtil.md5(newPassword));
            userBasicUpdateWrapper.set("update_time", DateUtil.getTime("yyyy-MM-dd HH:mm:ss"));
            if(userBasicService.update(userBasicUpdateWrapper)){
                redisTemplate.delete("forgotPwd_" + account); //密码修改成功，则清除短信验证码
                return Result.OK("密码修改成功");
            }
            return Result.OK("密码修改失败");
        }
        return Result.error("验证码错误");
    }


    /**
     * 通过id查询协议（不需要token校验）
     *
     * @param reqCommonModel
     * @return
     */
    @AutoLog(value = "通过id查询协议")
    @ApiOperation(value="通过id查询协议", notes="通过id查询协议")
    @PostMapping(value = "/findContractById")
    public Result<?> findContractById(@Valid @RequestBody ReqCommonModel reqCommonModel){
        return Result.OK(contractTemplateService.getById(reqCommonModel.getId()));
    }





    /**
     * 发送短信验证码
     */
    @AutoLog(value = "发送短信验证码")
    @ApiOperation(value="发送短信验证码", notes="发送短信验证码")
    @PostMapping(value = "/sendCode")
    public Result<?> sendCode(@RequestBody ReqUserLoginModel reqUserLoginModel){
        String account = reqUserLoginModel.getAccount();
        String codeType = reqUserLoginModel.getCodeType();
        if(oConvertUtils.isEmpty(account) || oConvertUtils.isEmpty(codeType)){
            return Result.error("必输项不能为空");
        }

        try {
            String phoneCode = CommonUtil.generateCode6();
            if (CodeTypeConstant.signUp.equals(codeType)){
                redisTemplate.opsForValue().set("signUp_" + account, phoneCode, 5*60, TimeUnit.SECONDS);
            } else if (CodeTypeConstant.forgotPwd.equals(codeType)) {
                redisTemplate.opsForValue().set("forgotPwd_" + account, phoneCode, 5*60, TimeUnit.SECONDS);
            } else if (CodeTypeConstant.jsPhoneChange.equals(codeType)) {
                redisTemplate.opsForValue().set("jsPhoneChange_" + account, phoneCode, 5*60, TimeUnit.SECONDS);
            } else {
                return Result.error("验证码类型不正确");
            }
//            return Result.OK("短信验证码发送成功", phoneCode);
//            return SendSmsUtil.sendSmsCodeResult(account, phoneCode);
            return DanMiSmsUtil.execute(account, phoneCode,DanMiSmsUtil.VERIFICATION);
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.error("短信验证码发送失败");
    }





    public static void main(String[] args) {
        System.out.println(SecureUtil.md5("123456"));
    }



}
